#pragma once
#include "XMsg.h"
#include "XComTask.h"
#include <functional>
// 不调用bufferevent
namespace xmsg
{
    class XMsgHead;
}
class XCOM_API XMsgEvent:public XComTask
{
public:
    typedef void(XMsgEvent::*MsgCBFunc)(xmsg::XMsgHead*head,XMsg *msg);
    // using MsgCBFunc=std::function<void(XMsgEvent*,xmsg::XMsgHead*head,XMsg *msg)>;
    /**
     * @brief 读取消息回调函数，处理接收到的消息并调用相应的回调函数。
     *
     * 该函数负责接收消息、检查消息是否接受完整，接收完整后调用void readCB(xmsg::XMsgHead*head,XMsg *msg)。
     */
    void readCB() override final;
    /**
     * @brief 处理消息读取事件的回调函数
     * 
     * 本函数根据消息类型调用相应的处理回调函数。它首先检查消息类型是否已在此对象中注册，
     * 如果没有注册，则记录一条调试日志并退出。如果找到了对应的回调函数，它将调用该回调函数
     * 来处理消息。处理完消息后，它将调用Clear函数来清理资源。
     * 如果不需要对消息分类处理可以重载
     * 
     * @param head 指向消息头部的指针，包含消息的元数据
     * @param msg 指向具体消息内容的指针，包含消息的详细信息
     */
    virtual void readCB(xmsg::XMsgHead*head,XMsg *msg);
    //////////////////////////////////////////
    /// 接收数据包，
    /// 1 正确接收到消息  (调用消息处理函数)
    /// 2 消息接收不完整 (等待下一次接收) 
    /// 3 消息接收出错 （退出清理空间）
    /// @return 1 2 返回true 3返回false
    bool RecvMsg();

    /////////////////////////////////////////
    /// 获取接收到的数据包，（不包含头部消息）
    /// 由调用者清理XMsg
    /// @return 如果没有完整的数据包，返回NULL
    XMsg *GetMsg();

    /**
     * @brief 发送消息事件
     *
     * 本函数负责将一个消息对象封装并发送出去。它首先检查消息对象是否有效，
     * 然后创建消息头，设置消息类型和消息体大小，接着序列化消息体和消息头，
     * 最后将消息头大小、消息头和消息体依次写入。
     *
     * @param type 消息类型，用于标识消息的种类
     * @param message 指向消息对象的指针，该对象包含实际的消息数据
     * @return true 如果消息成功发送，则返回true
     * @return false 如果消息发送失败，则返回false
     */
    bool SendMsg(unsigned int type, const google::protobuf::Message *message);
    /**
     * @brief 发送消息事件
     * 
     * 本函数负责将一个protobuf消息通过既定的通信渠道发送出去。
     * 它首先序列化消息内容和消息头，然后先发送消息头的大小，接着发送消息头，最后发送消息内容。
     * 
     * @param head 消息头指针，包含消息的元数据，如消息类型和消息大小
     * @param message 消息内容的指针，指向一个protobuf消息对象
     * @return true 如果消息发送成功
     * @return false 如果消息发送失败，包括参数为空指针、序列化失败或写操作失败
     */
    bool SendMsg(xmsg::XMsgHead *head, const google::protobuf::Message *message);
    /**
     * @brief 发送消息事件
     * 
     * 本函数负责将一个消息对象通过特定的通信渠道发送出去。它首先序列化消息头，
     * 然后发送消息头的大小，接着发送消息头本身，最后发送消息体。这个过程确保了
     * 消息的接收方可以准确地重构消息。
     * 
     * @param head 消息头的指针，包含了消息的各种元数据信息
     * @param message 消息体的指针，包含了实际要发送的数据
     * @return true 如果消息发送成功
     * @return false 如果消息发送失败
     */
    bool SendMsg(xmsg::XMsgHead *head, XMsg *message);
    bool Close() override;
    /////////////////////////////////////
    /// 清理缓存消息头和消息内容，用于接收下一次消息
    void Clear();
    // 注册消息回调函数
    // @param type 消息类型
    // @param func 回调函数
    static void RegCB(int type, MsgCBFunc func);
    void setIsRecvMsg(bool b){m_isRecvMsg = b;}
private:
    //
    bool m_isRecvMsg = true;
    xmsg::XMsgHead *pb_head_=nullptr;
    XMsg head_; //消息头
    XMsg msg_;  //消息内容
};

